home *** CD-ROM | disk | FTP | other *** search
- #include <A4Stuff.h>
- #include <Errors.h>
- #include <Gestalt.h>
- #include <TextUtils.h>
-
- // Constants
-
- #define kAllocChunk 20
-
- // Public Routines
-
- pascal void* main(int iRoutineSelector);
-
- pascal
- OSErr
- MySelectorFunction
- (
- OSType selector,
- long* response
- );
-
- pascal OSErr FindSelector(OSType selector, long* value);
- pascal OSErr RegisterSelector(OSType selector, long value);
-
- // The main entry point
-
- pascal
- void* // The routine pointer
- main
- (
- int iRoutineSelector // The routine name
- )
- {
- long oldA4 = SetCurrentA4 ();
- void* retval;
-
- if (iRoutineSelector == 1)
- {
- retval = (void*)RegisterSelector;
- }
- else
- {
- retval = (void*)FindSelector;
- }
-
- SetA4 (oldA4);
-
- return (retval);
- }
-
- // Globals
-
- static Handle gSelectors = nil;
- static Handle gValues = nil;
- static long gAllocSize = 0;
- static long gPatchCount = 0;
-
- // Local routines.
-
- static long FindPatch(OSType selector);
- static OSErr SetGestaltRoutine(OSType selector);
-
- // Find a patched selector.
-
- long FindPatch(OSType selector)
- {
- long oldA4 = SetCurrentA4 ();
- long i;
-
- for (i = 0; (i < gPatchCount) && gSelectors; i++)
- {
- if (selector == ((long*)(*gSelectors))[i])
- {
- SetA4 (oldA4);
- return i;
- }
- }
-
- SetA4 (oldA4);
-
- return -1;
- }
-
- // The selector function
-
- pascal
- OSErr
- MySelectorFunction
- (
- OSType selector,
- long* response
- )
- {
- long oldA4 = SetCurrentA4 ();
- long patchIndex = -1;
- OSErr err = noErr;
-
- patchIndex = FindPatch(selector);
-
- if (patchIndex < 0)
- {
- err = Gestalt(selector, response);
- }
- else
- {
- *response = ((long*)(*gValues))[patchIndex];
- }
-
- SetA4 (oldA4);
-
- return err;
- }
-
- // Public entry to find a selector
-
- pascal OSErr FindSelector(OSType selector, long* value)
- {
- long oldA4 = SetCurrentA4 ();
-
- OSErr err = noErr;
- long response = 0;
- long patchIndex = -1;
-
- patchIndex = FindPatch(selector);
-
- if (patchIndex >= 0)
- {
- response = ((long*)(*gValues))[patchIndex];
- *value = response;
- }
- else
- {
- err = Gestalt(selector, value);
- }
-
- SetA4 (oldA4);
-
- return err;
- }
-
- // Make an entry in the tables
-
- OSErr SetGestaltRoutine(OSType selector)
- {
- long oldA4 = SetCurrentA4 ();
- OSErr err = noErr;
- SelectorFunctionUPP oldFcn;
-
- err = ReplaceGestalt(selector, MySelectorFunction, &oldFcn);
-
- if (err == gestaltUndefSelectorErr)
- {
- err = NewGestalt(selector, MySelectorFunction);
-
- if (err == noErr)
- {
- err = ReplaceGestalt(selector, MySelectorFunction, &oldFcn);
- }
- }
-
- SetA4 (oldA4);
-
- return err;
- }
-
- // Register a selector
-
- pascal OSErr RegisterSelector(OSType selector, long value)
- {
- long oldA4 = SetCurrentA4 ();
- OSErr err = noErr;
- long patchIndex = -1;
-
- patchIndex = FindPatch(selector);
-
- if (patchIndex < 0)
- {
- if ((gAllocSize % kAllocChunk) == 0)
- {
- gAllocSize += kAllocChunk;
-
- if (gSelectors)
- {
- SetHandleSize(gSelectors, gAllocSize);
- }
- else
- {
- gSelectors = NewHandle(gAllocSize * sizeof(long));
- }
-
- if (gValues)
- {
- SetHandleSize(gValues, gAllocSize * sizeof(long));
- }
- else
- {
- gValues = NewHandle(gAllocSize);
- }
-
- patchIndex = gPatchCount;
- gPatchCount++;
- }
- }
-
- (((long*)(*gSelectors))[patchIndex]) = selector;
- (((long*)(*gValues))[patchIndex]) = value;
-
- SetGestaltRoutine(selector);
-
- SetA4 (oldA4);
-
- return (err);
- }
-